package zhongbo.javaweb.instagram.schedule;

import com.alibaba.fastjson.TypeReference;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import zhongbo.javaweb.instagram.dto.JsonRespDto;
import zhongbo.javaweb.instagram.enums.InsUrl;
import zhongbo.javaweb.instagram.enums.ServiceType;
import zhongbo.javaweb.instagram.service.ProcessService;
import zhongbo.javaweb.instagram.util.DateFormatUtil;
import zhongbo.javaweb.instagram.util.JsonRespUtil;
import zhongbo.javaweb.instagram.web.util.RestTemplateUtils;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 说明：
 *
 * @author zhongboWork
 * @version 1.0
 * @since 2022-01-06 18:48
 */
@Component
@Slf4j
@Data
public class HeartBeatCheckSchedule {

    @Autowired
    private RestTemplateUtils restTemplateUtils;
    @Autowired
    private ProcessService processService;

    @Value("${service.type}")
    private ServiceType serviceType;
    @Value("${service.middle.url}")
    private String middleUrl;

    @Value("${heartBeat.check.timeoutMs}")
    private long heatBeatTimeOutMs = 600000;
    @Value("${heartBeat.check.intervalMs}")
    private long heatBeatCheckIntervalMs = 60000;

    private long lastHeartbeat;

    private long lastCheckTime;

    //@Scheduled(fixedDelay = 1000)
    public void checkHeartbeat() throws InterruptedException {
        if (System.currentTimeMillis() - lastCheckTime > heatBeatCheckIntervalMs) {
            lastCheckTime = System.currentTimeMillis();
            if (serviceType == ServiceType.client) {
                log.info("======== client heart check, timeout config {}", DateFormatUtil.formatMs(heatBeatTimeOutMs));
                syncLastHeartBeat(middleUrl);
                long heartTimeOuted = System.currentTimeMillis() - lastHeartbeat - heatBeatTimeOutMs;
                if (heartTimeOuted > 0) {
                    log.warn("心跳已超时 {}ms 触发心跳超时事件!", heartTimeOuted);
                    doHeartTimeOut();
                }
            }
        }
    }

    private void doHeartTimeOut() throws InterruptedException {
        processService.rollNextProxy();
        TimeUnit.SECONDS.sleep(10);
        processService.restartChrome();
        TimeUnit.SECONDS.sleep(30);
    }

    private void syncLastHeartBeat(String middleUrl) {
        JsonRespDto<Long> respDto = restTemplateUtils.get(middleUrl + InsUrl.LAST_HEART_BEAT, new TypeReference<JsonRespDto<Long>>() {
        });
        long past = System.currentTimeMillis() - lastHeartbeat;
        if (JsonRespUtil.isSuccess(respDto)) {
            lastHeartbeat = respDto.getData();
            log.warn("获取心跳时间! {} past {}", DateFormatUtil.format(lastHeartbeat), DateFormatUtil.formatMs(past));
        } else {
            log.warn("获取心跳失败! past {}", DateFormatUtil.formatMs(past));
        }
    }

    public void heartBeat() {
        lastHeartbeat = System.currentTimeMillis();
    }
}
